Saltar a contenido

📘 Clase 06: Arquitecturas RAG (Retrieval-Augmented Generation)

  • :material-bookmark: Curso: Curso 3: Creación y Desarrollo de Agentes de IA (CLASE 06)
  • :material-signal-cellular-outline: Nivel: Nivel 3 - Avanzado
  • :material-lightbulb-on: Metáfora Central: «El Estudiante con el Libro Abierto en el Examen (Búsqueda + Contexto)»
  • :material-laptop: Wisrovi Studio (Local): 🚀 Abrir Reto👨‍🏫 Modo Tutor
  • :material-file-pdf-box: Manual PDF Oficial: Descargar clase-06-arquitecturas-rag.pdf

Open In Colab Abrir en Studio Local Ver en GitHub


1. 💡 Fundamentación Teórica y Modelo Mental

Aumentar el conocimiento del LLM inyectando fragmentos recuperados en tiempo real: 1. Pipeline RAG: Ingestión -> Chunking -> Vectorización -> Búsqueda Top-K -> Inyección en Prompt. 2. Reducción de Alucinaciones: El LLM cita textualmente la información del contexto provisto. 3. Métricas de Relevancia: Score de similitud para filtrar documentos irrelevantes.

🌟 Modelo Mental de la Sesión: «El Estudiante con el Libro Abierto en el Examen (Búsqueda + Contexto)»

En esta sesión anclamos el aprendizaje en la metáfora del mundo real para visualizar cómo fluyen las estructuras de datos y el flujo de ejecución en la memoria.


2. 🗺️ Arquitectura de Ejecución y Diagrama de Flujo

flowchart TD
    A["👤 Pregunta Usuario"] --> B["🔍 Búsqueda Vectorial Top-K"]
    B --> C["📚 Documentos Relevantes Recuperados"]
    C & A --> D["🧠 Prompt con Contexto Aumentado"]
    D --> E["🎯 Respuesta Precisa y Verificable"]
    style A fill:#1e293b,color:#ffffff,stroke:#3b82f6,stroke-width:2px
    style B fill:#d97706,color:#ffffff,stroke:#fbbf24,stroke-width:2px
    style C fill:#0f766e,color:#ffffff,stroke:#2dd4bf,stroke-width:2px
    style E fill:#059669,color:#ffffff,stroke:#34d399,stroke-width:2px

3. 💻 Código de Implementación Práctica

```python def simple_rag_mock(query: str, corpus: list[str]) -> list[str]:

Filtrar documentos que contengan palabras clave de la consulta

palabras = set(query.lower().split()) return [doc for doc in corpus if any(p in doc.lower() for p in palabras)]

docs = ["Python 3.12 incluye mejoras de rendimiento", "Docker permite empaquetar aplicaciones"] print("Recuperado:", simple_rag_mock("rendimiento en Python", docs)) ```

```python contexto = "\n".join(["- Doc 1: FastAPI", "- Doc 2: Uvicorn"])

prompt_rag = f"Contexto:\n{contexto}\n\nPregunta: ¿Qué es FastAPI?" print(prompt_rag) ```


4. 🛡️ Buenas Prácticas PEP 8: Antipatrones vs Código Pythonic

⚠️ Cuidado con los Antipatrones

prompt = f'Contexto:\n{20_chunks_desordenados}'  # ❌ Degradación de atención
# Selecciona Top 3 a 5 chunks relevantes y reordénalos con un Re-ranker ✅

5. 🏋️ Desafío Práctico de la Clase

🎯 Enunciado del Reto

Crea una clase SimpleRAGIndex con métodos: agregar_documento(self, doc_id: str, texto: str, vector: list[float]) y buscar_similares(self, vector_query: list[float], top_k: int = 2) -> list[str] que retorne los IDs de los documentos con mayor similitud coseno.

⚡ Resolución Híbrida en 1 Clic (Local + Web)

Si tienes ejecutando wisrovi ui en tu terminal local, puedes 🚀 Abrir este Reto directamente en tu Studio Local (127.0.0.1:8501) para escribir tu código con auto-formateo AST, inspeccionar variables en el Heap/Stack y evaluarlo con pruebas en tiempo real.

```python import math

from typing import List, Dict, Tuple

class SimpleRAGIndex: def init(self): self._docs: Dict[str, Tuple[str, List[float]]] = {}

def agregar_documento(self, doc_id: str, texto: str, vector: List[float]):
    self._docs[doc_id] = (texto, vector)

def _similitud(self, v1: List[float], v2: List[float]) -> float:
    dot = sum(a * b for a, b in zip(v1, v2))
    norm1 = math.sqrt(sum(a * a for a in v1)) or 1e-9
    norm2 = math.sqrt(sum(b * b for b in v2)) or 1e-9
    return dot / (norm1 * norm2)

def buscar_similares(self, vector_query: List[float], top_k: int = 2) -> List[str]:
    # ✍️ Ordena por similitud descendente y retorna top_k IDs
    scores = []
    for doc_id, (_, vec) in self._docs.items():
        s = self._similitud(vector_query, vec)
        scores.append((doc_id, s))
    scores.sort(key=lambda x: x[1], reverse=True)
    return [doc_id for doc_id, _ in scores[:top_k]]

```
💡 Pista Socrática 1

💡 Pista 1: Almacena los documentos como self._docs[doc_id] = (texto, vector).

💡 Pista Socrática 2

💡 Pista 2: Para cada documento calcula la similitud contra vector_query.

💡 Pista Socrática 3

💡 Pista 3: Ordena por puntaje descendente scores.sort(key=lambda x: x[1], reverse=True) y retorna los doc_id del top_k.

Para resolver este ejercicio en tu entorno: 1. Abre el archivo ejercicios/reto.py de esta clase en Visual Studio Code o utiliza wisrovi ui / wisrovi tutor. 2. Implementa tu solución cumpliendo los requisitos y contratos de tipado. 3. Valida tus resultados ejecutando las pruebas unitarias:

pytest tests/curso_03/test_clase_06_arquitecturas_rag.py


6. 📚 Fuentes y Bibliografía Recomendada